  -=( 7A69#11 )=--=( art17 )=--=( Crakeando el L0phtcrack )=--=( Lykeios )=-

REGISTRANDO EL L0phtcrack v3
============================

Indice
======

1.- Introduccion
2.- Breve Historia de las Proteciones del L0phtcrack
3.- Lo Que Necesitaremos
4.- Una Tarde de Crackeo
        4.1.- Primer Vistazo y Primer Intento (por si acaso ;])
        4.2.- Siguiendo la Pista
        4.3.- Nos Registramos!!!
        4.4.- Todos los Caminos LLevan a Roma
5.- Despedida y Cierre


1.- Introduccion
^^^^^^^^^^^^^^^^
Buenas noches. Soy Lykeios.

Todo esto comenzo a la vuelta del puente de Semana Santa. Acababa yo de llegar
a casa bastante hecho polvo; eran casi las 12 de la noche del domingo y tenia
un sueo de la ostia despues de pasarme todo el puente de juerga con media
pandilla en casa de una amiga. "Uffff y ademas maana empiezo el puto curso.
Joooder!"

Me conecto un minuto antes de pirarme a la cama prometiendome que solo voy a
leer el correo; pero claro, entre mail y mail no puedo evitar darme una vuelta
por las webs de rigor ;].

Y cual no sera mi sorpresa al encontrarme en 'packetstorm' una nueva version
del L0phtcrack. Vaya, no se si se esperaba o no, pero la verdad que yo no
tenia ni idea de que fueran a sacarla :?

Me lo bajo rapidamente y ya empiezo a pensar en lo que terminaria siendo este
articulo.

No es que el programa me haya sido de excesiva utilidad en el pasado, pero la
verdad es que, para los que andamos navegando por ambos mundos, esta es una de
esas extraas ocasiones en las que podemos aplicar ingenieria inversa a algun
programa de hack; y eso motiva bastante, aunque luego la dificultad sea
minima, como veremos mas adelante...

No lo dudes ni un minuto y enviame un mail si detectas cualquier error. Ya
sabes que, como siempre, me puedes mandar cualquier duda, sugerencia, critica
o lo que sea *referente al texto* a: lykeios@bigfoot.com

Bueno pues, sin mas preambulos, veamos con que me encontre la noche siguiente,
despues de haber descansado ;].


2.- Breve Historia de las Proteciones del L0phtcrack
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Pues bien, lo de "historia de las protecciones del L0phtcrack" es poco menos
que una broma ;].

La verdad es que nunca se han molestado mucho en el tema. Aun recuerdo con una
sonrisa mis primeros pinitos en el mundillo crackeando la version 2.5.

Recapitulemos un poco. El limite de tiempo  de la version 2.0 se podia saltar
tranquilamente con solo cambiar un salto condicional por uno incondicional.
Lo podeis ver en el articulo que aparecio en SET21 (articulo 0x11).

Para crackear la version 2.5 no hacia falta mucho mas. Recuerdo que para
conseguir que te aceptara cualquier registro como valido bastaba con parchear
una funcion (esta vez se habian molestado en llamarla desde varios sitios
dentro del programa, y por eso cambiar el salto condicional no era
suficiente).

No era mas que el tipico: xor eax,eax
                          inc eax
                          ret

Y listo. No hacia ya falta ni meter un codigo a bulto. Aparecias directamente
como registrado.

Ni que decir tiene que las cadenas se encontraban facilmente en las "String
References" del W32Dasm y que los saltos pertinentes estaban por ahi cerca
(vamos, que no hacia falta ni el debugger). Si ademas sumamos que las ventanas
de error eran (y siguen siendo ;]) las tipicas MessageBoxA..... pues eso, que
la cosa estaba bastante facil.

De las versiones anteriores la verdad que no se nada, pero visto lo visto
no debia de ser muy dificil (si es que estaban protegidas).

En la version 3 al menos se han molestado en ocultar las cadenas, pero bueno,
no adelantemos acontecimientos....


3.- Cosas Que Necesitaremos
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Veamos que es lo que vamos a necesitar para destripar a nuestra pequea
victima (herramientas y conocimientos):

        - Lo primero y mas importante que necesitaras seran aproximadamente
          media docena de neuronas (a poder ser sanas ;]). (Iba a pedir una
          docena, para que supieras tambien cuando utilizarlas; pero no es
          cuestion de complicarlo innecesariamente: ya te aviso yo ;].)

        - Tambien necesitaras saber algo de programacion en ASM. Si no es tu
          caso busca por la red, existen cursos bastante buenos tanto en
          Ingles como en Espaol.

        - Desde luego necesitas tener el L0phtcrack v3 instalado ;]. (Ya se
          que esto es bastante obvio, pero como tampoco pedia demasiadas
          neuronas......).

        - Vas a necesitar un debugger. Yo uso el SoftICE 4.00 (para Win9x),
          pero tu puedes usar el que mas te guste; es indiferente.

        - Tambien necesitaras un editor hexadecimal para modificar el
          ejecutable. El que yo uso es el UltraEdit-32 v5.10a. Tu usa el que
          quieras.

        - Un desensamblador no es estrictamente necesario, pero si bastante
          recomendable. El mio es el W32Dasm v8.93, pero como siempre tu usa
          el que quieras.

        - Bueno y tambien uso las utilidades FILEMON y REGMON para ver un poco
          lo que hace el ejecutable, pero son totalmente prescindibles.

Y ya esta, creo que no vamos a necesitar nada mas. Asi que ha llegado el
momento de empezar a crackear (que ya iba siendo hora).


4.- Una Tarde de Crackeo
^^^^^^^^^^^^^^^^^^^^^^^^
    
    4.1.- Primer Vistazo y Primer Intento (por si acaso ;])
    
    Pues bien, comienzo como siempre rulando el FILEMON y el REGMON para ver
    a que narices accede el L0phtcrack v3 (en adelante LC3) durante el
    arranque.

    Les aplico a ambos un filtro al proceso "lc3" y sin mas  rulo el LC3,
    espero a que arranque y luego lo cierro.

    Bueno pues por un lado en el FILEMON veo como accede a ficheros de un
    directorio oculto (\windows\applog\): LC3.LGC, LC3.LGD, etc (hay algunos
    mas). Voy por alli a ver que tienen y la verdad que no saco nada en
    limpio, son unas tablas con datos que para mi no tienen mucho sentido.
    Otros como LC3SETUP.~~C y LC3SETUP.~~D son creados durante la instalacion
    y mantienen esa fecha, por lo que quiza se usen para testear el periodo
    de prueba (pero yo no voy a atacar por ahi).

    Por otro lado en el REGMON puedo ver un monton de accesos al registro,
    pero el que mas me llama la atencion es sin duda el siguiente (que aparece
    dos veces):

  \HKCU\Software\Security Software Technologies\LC3\Registration\Unlock Code

    Y como peticion veo: QueryValueEx, o sea que comprueba si esta ahi o no.
    Yo, ni corto ni perezoso, me rulo el RegEdit, me voy para alli y compruebo
    que efectivamente esa clave no existe.

    No puedo evitar que una sonrisa de picardia me aparezca en la boca... Ya
    se que las protecciones del LC no son nada del otro mundo pero... no... no
    puede ser tan facil... o si??

    Como probar me sale gratis y solo llevo unos 10 minutos con esto pues no
    me lo pienso mucho, creo en \Registration\ una clave llamada "Unlock
    Code", le meto un valor a bulto y salvo.

    Vuelvo a arrancar el LC3 y no, parece que no hubo suerte, no son tan
    torpes ;]. La vuelvo a borrar con el RegEdit y sigo.

    Bueno pues como por aqui no veo nada mas que sea digno de mencion, va
    siendo hora de echarle un vistazo mas de cerca al programa en cuestion.

    Arranco una vez mas el LC3 y me aparece directamente una ventana con un
    mensaje tal que asi:

    "LC3 trial version

     LC3

     password
     auditing                   (y un dibujillo de hexa por aqui)
     and
     recovery

                                                                security
                                                                software
                                                                technologies"

    Si, si, lo que tu digas... "auditing and recovery" jeje ;]

    Bueno, y en la parte de abajo vemos: "15 Days until trial version will
    expire." Pues esto mismo es lo que nosotros queremos evitar, que 'expire'
    ;]

    Tambien podemos ver 3 botones: "Trial"  "Register" y "Help".

    Dandole a "Help" te muestra la web donde te da ayuda para registrarse y
    te cuenta las maravillas que hace el programilla. Dando una vuelta por
    la pagina web de L0pht, podemos ver que una licencia individual te sale
    al modico precio de 249$ (dolares) que no se yo quien coo los va a pagar.
    Bueno, creo que obviamente este no es nuestro sendero ;]

    Si le damos al de "Trial" nos vamos al programa en si, solo que la funcion
    de 'brute force' esta deshabilitada. Aprovechar para echarle un vistazo si
    quereis. Si ya habeis terminado vuestro periodo de prueba os saldra un
    mensajillo de error (sobra decir que es una MessageBox) que os dice:

    "Your trial version of LC3 has expired. You must register the software to
    continue using it. Click on "Register" when you start LC3 for more info."

    Ok, pues eso mismo es lo que vamos a hacer nosotros, darle al boton de
    "Register". Nos aparece una pequea ventana con dos campos de datos:
    "Serial Number" que ya esta rellenado y no podemos cambiar, y "Unlock
    Code" que estara en blanco para que lo rellenes. Tambien hay dos botones:
    "Ok" y "Cancel" (que paso de explicar ;]).

    Muy bien, la cosa funciona asi: durante el proceso de instalacion el LC3
    calcula un "Serial Number" especifico para esa maquina, que es fijo y,
    por lo tanto, no va a cambiar aunque desinstales-reinstales. Luego tu, se
    supone que pruebas el programilla, te enamoras de el y llamas rapidamente
    a los de L0pht, les dices el "Serial", pagas y te dan el "Unlock Code"
    especifico para esa maquina.
                           
    La unica diferencia entre lo que han pensado ellos y lo que hemos pensado
    nosotros es que: ni les vamos a llamar, ni, por supuesto, les vamos a
    pagar un duro ;].

    Como decia mi abuelo: "Lo primero es... antes." Asi que comenzamos por
    meter un codigo a bulto (en mi caso "1122334455") y le damos al boton de
    "Ok". Al momento nos aparece una ventana de error con el siguiente
    mensaje:

    "You have entered an invalid code. Please try again."

    No, por el momento no voy a intentarlo mas. Recordando la historia de las
    protecciones del LC, me apunto ese mensaje y me voy rapidamente al
    W32Dasm. Desensamblo el 'lc3.exe' y le doy al boton "Strn Ref" (tambien
    valdria dandole al menu "Refs" -> "String Data References") y busco por
    ahi la cadena que apunte antes. Pero no la veo por ningun lado. Tampoco
    veo nada del estilo "...successfully...", "...success..." ni nada de lo
    que suele aparecer en los mensajes cuando te registras correctamente.

    Bueno, pues parece que algo si que han cambiado esta vez; han ocultado las
    referencias a cadenas (al menos a las importantes). Significara esto que
    han aprovechado para mejorar sustancialmente el mecanismo de proteccion?
    El ejecutable no esta comprimido, pero aun puede que hayan metido algun
    checksum, o alguna tecnica anti-debuggin, o algo.... Pero la verdad es que
    no...

    Sigamos. Parece ser que vamos a tener que tracearlo. Ha legado la hora de
    sacar al SICE al terreno de juego ;].


    4.2.- Siguiendo la Pista

    Como introduccion a este apartado os contare que, si para algo me ha
    servido escribir este articulo, ha sido para conseguir de una puetera vez
    que una version del SICE me tirara bien en el puto WinME. Despues de
    aplicar el famoso parche para el arranque de Win, la v3.25 me lo colgaba
    (no me preguntes por que) y la v4.05 me daba un mensaje chungo y no se
    cargaba (no se si seria que la copia estaba mal o alguna otra cosa :? ).

    El caso es que la v4.00 me va como dios y ya soy un hombre feliz ;-).

    Bien, sigamos donde lo dejamos. Arrancamos windows con el SICE cargado (yo
    casi siempre lo tengo asi) y rulamos el LC3 una vez mas (y no la ultima).
    Aparecemos en la ventana de "LC3 trial version" con los tres botones, le
    damos a "Register" y en la ventana de registro metemos otra vez un codigo
    cualquiera (yo meti otra vez "1122334455"), pero ANTES de darle al boton
    de "Ok" pasamos al SICE con "ctrl+d".

    Bien, ahora pensemos (no mucho, la verdad), el programa tendra que leer de
    alguna forma el codigo que le metimos, asi que ponemos uno de los
    breakpoints mas tipicos para esto y que ademas nunca falla:

    bpx hmemcpy

    Volvemos a dar "ctrl+d" y en la ventanita le damos al boton de "Ok".
    Inmediatamente aparecemos en el SICE, hemos parado porque se llama a
    HMEMCPY, como habiamos supuesto. Pero es bastante probable que lo que este
    leyendo sea el "Serial", asi que doy una vez mas "ctrl+d" para llegar a la
    llamada que lee el codigo. Estamos en el codigo de HMEMCPY, para salir
    pulsamos F12 (ir hasta el siguiente ret; o sea, salir de la funcion) y
    vemos que estamos en USER.DLL (como era de esperar), puedes verlo en la
    seccion de codigo del SICE. Damos unas cuantas veces mas a F12 hasta que
    lleguemos al codigo del LC3 (lo puedes ver en la ventana de codigo del
    SICE, aparecera algo asi "lc3.text+....").

    Podemos ver esto:

:0046A0A5 50                      push eax
:0046A0A6 56                      push esi

* Reference To: USER32.GetWindowTextA, Ord:0162h
                                  |
:0046A0A7 FF1540D54700            Call dword ptr [0047D540] <- Venimos de aqui
:0046A0AD 8B4D10                  mov ecx, dword ptr [ebp+10] <- Estamos aqui
:0046A0B0 6AFF                    push FFFFFFFF
:0046A0B2 E8D54DFFFF              call 0045EE8C
:0046A0B7 EB0B                    jmp 0046A0C4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046A08F(C)
|
:0046A0B9 8B4510                  mov eax, dword ptr [ebp+10]
:0046A0BC FF30                    push dword ptr [eax]
:0046A0BE 56                      push esi
:0046A0BF E843F5FFFF              call 00469607

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046A0B7(U)
|
:0046A0C4 5F                      pop edi
:0046A0C5 5E                      pop esi
:0046A0C6 5D                      pop ebp
:0046A0C7 C20C00                  ret 000C

    Podemos observar que venimos de una llamada a GetWindowTextA. Si nos
    fijamos un poco vemos que en EAX esta la longitud de la cadena que metimos
    como codigo:

    EAX = 0x0A (10 en decimal)

    Y vemos que la instruccion sobre la que estamos va a cargar un valor en
    ECX. Le damos a F8 para que se ejecute y miramos a ver que es lo que hay
    ahora alli:

    d ecx

    Y en la ventana de datos deberia estar viendo el codigo que introduje,
    pero no es asi, solo hay datos sin demasiado sentido para mi. Hummmmmm
    pensemos: las "String References" de las ventanas las habian ocultado...
    habran hecho lo propio con estas?? Sera un puntero a la cadena?? Veamos:

    d *ecx

    Efectivamente, ahora puedo ver perfectamente en la ventana de datos mi
    codigo mas falso que Judas (pero que nos va a ayudar mucho ;]). Lo que
    ha pasado es que el programador en lugar de usar una cadena normal
    (char *), ha usado un puntero a cadena (char **), y con eso esperaba
    despistarnos...... ;]

    Pues bien, lo que yo quiero hacer ahora es seguirle la pista a esa cadena
    que hay en *ECX, ya que en algun momento tendra que comprobar si es la
    correcta o no, no? Quito el breakpoint que tenia antes:

    bd 0

    Y meto mi nuevo y flamante:

    bpm *ecx

    Estamos listos para darle un poco de sedal a nuestro pececillo, en el
    fondo sigue estando bajo nuestro control ;]. Lo dejamos correr: "ctrl+d".

    Aparecemos otra vez en el SICE. Nuestro breakpoint ha funcionado, por lo
    que deben de estar haciendo algo con nuestro codigo. Veo que estamos
    en una funcion de KERNEL32.DLL (fijate en la ventana de codigo), un par
    de F12's para volver al codigo del LC3 y veo que era una llamada a
    'lstrlen'. En EAX volvemos a tener 0x0A. No es lo que nos interesa. Lo
    dejamos correr de nuevo: "ctrl+d".

    Al instante volvemos a estar en el SICE viendo esto:

      :
      :
:0044E5AA 8BFF                    mov edi, edi

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0044E5B8(C), :0044E5D8(C)
|
:0044E5AC 0AC0                    or al, al
:0044E5AE 742E                    je 0044E5DE
:0044E5B0 8A06                    mov al, byte ptr [esi]
:0044E5B2 46                      inc esi
:0044E5B3 8A27                    mov ah, byte ptr [edi]
:0044E5B5 47                      inc edi     <---------- Aparecemos aqui
:0044E5B6 38C4                    cmp ah, al
:0044E5B8 74F2                    je 0044E5AC
:0044E5BA 2C41                    sub al, 41
:0044E5BC 3C1A                    cmp al, 1A
:0044E5BE 1AC9                    sbb cl, cl
:0044E5C0 80E120                  and cl, 20
:0044E5C3 02C1                    add al, cl
:0044E5C5 0441                    add al, 41
:0044E5C7 86E0                    xchg al, ah
:0044E5C9 2C41                    sub al, 41
:0044E5CB 3C1A                    cmp al, 1A
:0044E5CD 1AC9                    sbb cl, cl
:0044E5CF 80E120                  and cl, 20
:0044E5D2 02C1                    add al, cl
:0044E5D4 0441                    add al, 41
:0044E5D6 38E0                    cmp al, ah
:0044E5D8 74D2                    je 0044E5AC
:0044E5DA 1AC0                    sbb al, al
:0044E5DC 1CFF                    sbb al, FF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044E5AE(C)
|
:0044E5DE 0FBEC0                  movsx eax, al
:0044E5E1 EB78                    jmp 0044E65B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044E5A6(C)
|
:0044E5E3 F0                      lock
:0044E5E4 FF0568BF6C00            inc dword ptr [006CBF68]
      :
      :
    
    Como puedes ver, un trozo de codigo mas que interesante (la funcion es
    mucho mayor, pero como tampoco la voy a analizar paso de ponerosla). Doy
    a F12 para ver desde donde han llamado a esta funcion (y como ;]).

    La verdad que no aparezco en un sitio demasiado interesante, voy a un
    salto incondicional que me manda al final de la funcion. Otra vez F12 y
    aparezco aqui:

      :
      :
:00420235 8B45E4                  mov eax, dword ptr [ebp-1C]
:00420238 8B8810010000            mov ecx, dword ptr [eax+00000110]
:0042023E 8D55C8                  lea edx, dword ptr [ebp-38]
:00420241 52                      push edx    <---- "Unlock Code" correcto ;]
:00420242 51                      push ecx    <---- Nuestro codigo falso
:00420243 E884700200              call 004472CC     <---- Venimos de aqui
:00420248 83C408                  add esp, 00000008 <---- ** Estamos aqui **
:0042024B 85C0                    test eax, eax     <---- La funcion devuelve?
:0042024D 7533                    jne 00420282      <---- Salto interesante
:0042024F 8B4DE4                  mov ecx, dword ptr [ebp-1C]
:00420252 C7811401000000000000    mov dword ptr [ebx+00000114], 00000000
:0042025C 8B8110010000            mov eax, dword ptr [ecx+00000110]
:00420262 50                      push eax
:00420263 6820486D00              push 006D4820
:00420268 6800486D00              push 006D4800
:0042026D E8C0D80400              call 0046DB32
:00420272 33C0                    xor eax, eax
:00420274 50                      push eax
:00420275 50                      push eax
:00420276 68C0496D00              push 006D49C0
:0042027B E8009B0400              call 00469D80
:00420280 EB0E                    jmp 00420290

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042024D(C)
|
:00420282 33C0                    xor eax, eax
:00420284 50                      push eax
:00420285 50                      push eax
:00420286 68004A6D00              push 006D4A00
:0042028B E8F09A0400              call 00469D80

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00420280(U)
|
:00420290 8D75C8                  lea esi, dword ptr [ebp-38]
:00420293 33C0                    xor eax, eax
:00420295 8906                    mov dword ptr [esi], eax
:00420297 894604                  mov dword ptr [esi+04], eax
      :
      :

    No hace falta ser un lince para darse cuenta que estamos en el lugar
    adecuado, verdad? ;] Podemos ver como se pushean en la pila (argumentos)
    dos cadenas, tomo nota para mirar mas tarde a ver que tienen (ya os lo he
    puesto ahi para que no tengais que trabajar mucho ;]. Basta con que useis
    el breakpoint que pongo en el 'call' dentro de poco y mireis lo que hay
    en ECX y EDX: 'd ecx'  y 'd edx').


    4.3.- Nos Registramos!!!

    Despues podemos ver como se llama a la funcion de la que nosotros venimos
    (que sera la que las compara), luego se comprueba que es lo que nos ha
    devuelto esa funcion (test eax,eax): si no es 0 salta y si es 0 sigue sin
    saltar.

    Tal y como estamos ahora vamos a saltar (EAX != 0) asi que parece que lo
    que nos interesa es que NO salte, o sea que en vez de 'jne 00420282'
    tengamos 'je 00420282'.

    Quito los breakpoints que tenia antes:

    bc *

    Pongo un punto de ruptura en la llamada a la funcion (por si lo necesito
    mas adelante):

    bpx cs:00420243

    Cambio el salto condicional en el SICE, con:

    e 0042024D

    Y cambio el '75' que hay por un '74'.

    Lo dejo que rule con "ctrl+d" y... bingo!!! Nos aparece una preciosa
    ventana con el mensaje:

    "You have succesfully registered LC3."

    jejeje Le damos a aceptar y llegamos a la ventana del LC3 y en el
    "About.." vemos nuestro codigo falso aceptado como bueno. Cierro y vuelvo
    a rular el LC3 para comprobar que todo va bien y.... coo, esto no parece
    que este funcionando como deberia. Estamos de nuevo en la ventana del
    periodo de prueba con los tres botones: "Trial", "Register" y "Help".

    Bien, no asustarse. Ya me extraaba a mi que si en la version 2.5
    comprobaban desde varios sitios no lo fueran a hacer en esta.

    Pero ya no es ningun problema: sabemos cual es la funcion que compara,
    sabemos que tiene que devolver 0 (para que no salte) y ademas tenemos un
    punto de ruptura justo en ella (por si nos hiciera falta).

    Yo a partir de aqui ya no use el SICE; me fui tranquilamente al W32Dasm,
    desensamble el 'lc3.exe' y me fui a la posicion '00420243' con "Goto Code
    Location", que es la del call:

    :00420243 E884700200              call 004472CC

    Una vez que estoy encima le doy a "Execute Call" y aparezco aqui:

* Referenced by a CALL at Addresses:
|:0041FD24   , :00420243   , :00446ED3   , :00446EE4   , :00446EF5   
|:00446F06   
|
:004472CC 55                      push ebp
:004472CD 8BEC                    mov ebp, esp
:004472CF 83EC0C                  sub esp, 0000000C
:004472D2 833DBCC06C0000          cmp dword ptr [006CC0BC], 00000000
:004472D9 53                      push ebx
:004472DA 56                      push esi
:004472DB 57                      push edi
:004472DC 7512                    jne 004472F0
:004472DE FF750C                  push [ebp+0C]
:004472E1 FF7508                  push [ebp+08]
:004472E4 E8A7720000              call 0044E590
:004472E9 59                      pop ecx
:004472EA 59                      pop ecx
:004472EB E96C010000              jmp 0044745C    
      :
      :

    Como podeis ver a esta funcion se la llama desde seis sitios distintos,
    por eso no nos valia parchear un solo salto. Lo que yo quiero hacer ahora
    es parchear esa funcion para que devuelva siempre 0; o sea que le voy a
    meter al principio:

    33 C0   xor eax,eax  // Pon EAX a 0
    C3      ret          // Retorna

    Arranco el UltraEdit. Solo tendre que cambiar esos 3 bytes, pero primero
    tomo una cadena de codigo que no se repita para estar seguro que parcheo
    en el lugar adecuado:

    Busco:        55 8B EC 83 EC 0C 83 3D BC
                  || || ||
    Cambio por:   33 C0 C3 ...esto lo dejas igual...

    Una vez hecho el cambio, salvalo (ya se encarga el UltraEdit de hacer una
    copia de seguridad el solito).

    Cierro el UltraEdit y rulo el LC3 a ver que pasa. Y listo!! No te pide un
    codigo siquiera, te da ya por registrado. Bueno, mejor dicho: a mi me da
    como registrado, porque ya tenia una entrada falsa en el registro (aquel
    "Unlock Code" que veiamos al principio); al cambiar el salto con el SICE
    te lo crea, aunque luego no te registre del todo. Muy bien, me lo cargo
    (procedimiento standard para "desregistrar" el LC3, lo borras e
    inmediatamente dejas de estar registrado. Por si quieres seguir jugando
    un poco con el como hice yo ;]).

    Dejo el cambio en el SICE como estaba (vuelvo a poner '75'). Vuelvo a
    rular el LC3, me salta la ventana de "Trial", doy a "Register", meto lo
    que me de la gana en el campo "Unlock Code" y listo!! Esta vez si que me
    registra de forma definitiva! ;]


    4.4.- Todos los Caminos LLevan a Roma

    No hace falta ni comentar que esta no es la unica forma de crackearlo.
    Ni siquiera creo que fuera la mas facil.

    Por un lado ya vimos que la llamada que realizaba para leer el codigo de
    la ventana era un GetWindowTextA. Dicho de otra forma: si en vez de usar
    un breakpoint en HMEMCPY lo hubieramos puesto en GetWindowTextA hubieramos
    podido crackearlo exactamente igual que lo que ya vimos.

    Por otro lado, como ya comente varias veces, las ventanas de mensajes que
    usa el programa son MessageBoxA. El mensaje de

    "You have entered an invalid code. Please try again."

    no es ninguna excepcion. Asi que probe a meter un punto de ruptura en ella
    justo antes de introducir un codigo a bulto.

    bpx messageboxa

    Vuelvo a windows con "ctrl+d" y le doy al boton de "Ok". Inmediatamente
    caigo en el SICE, como era de esperar, y veo que estoy en una funcion de
    USER32.DLL. Le doy a F12 para salir de ella, aparezco en windows con el
    mensaje de error, le doy al boton de "Aceptar" y vuelvo al SICE.

    Ahora si estoy en el codigo del LC3, en concreto en '00469D51'. Nada
    interesante por aqui, asi que le doy a F12. Y aparezco en '00469DA2'.
    Aunque yo en ese momento no me di cuenta (ni falta que hace ;]), puedes
    ver un par de "call 00469D80" en el trozo de codigo que te pastee un
    poco mas arriba. En concreto en '0042027B' y '0042028B' ;]

    Si no te das cuenta no pasa nada, volvemos a darle a F12 para salir de la
    funcion y aparecemos aqui:

      :
      :
:00420286 68004A6D00              push 006D4A00
:0042028B E8F09A0400              call 00469D80   <-- Venimos de aqui

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00420280(U)
|
:00420290 8D75C8                  lea esi, dword ptr [ebp-38] <- Estamos aqui
:00420293 33C0                    xor eax, eax
      :
      :

    Por si aun no te has dado cuenta, estamos un poco mas abajo del salto
    aquel que parcheamos. En concreto ese salto nos enviaba a:

:0042024D 7533                    jne 00420282

    O sea, justo encima de la llamada al mensaje de error. En fin... sobran
    los comentarios ;].

    
5.- Despedida y Cierre
^^^^^^^^^^^^^^^^^^^^^^
Como puedes ver el programa se crackeaba facilmente con algunos de los puntos
de ruptura mas tipicos. Teniendo en cuenta que nos llega de la mano de los
de L0pht, pues resulta un tanto triste... yo sigo sin creerme que haya nadie
mentalmente sano que pague casi 250 dolares por esto... pero quien sabe, hay
gente pa' to'! ;]

En fin seores, nada mas por hoy. Quiero darle las gracias a Marconi por
haberme revisado el articulo y por la cantidad de veces que me ha resuelto
dudas: un saludo chavalote! ;-]

Tambien quiero saludar a toda la gente de El_Liceo, y tambien a MORTIIZ,
AiNaKeR, Ripe, Anarion, Jafar, mnm y resto de pea del canal #root ;].

-=(EOF)=-
